package com.ctshk.rpc.iotc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.air.service.IAirProductService;
import com.ctshk.rpc.airexpress.service.IAirportExpressService;
import com.ctshk.rpc.bus.service.IBusProductService;
import com.ctshk.rpc.custom.service.ICustomizedTripScheduleService;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.finance.service.IFinanceOnAccountCurrencyQuotaService;
import com.ctshk.rpc.iotc.dto.OperateBankPreferenceListDTO;
import com.ctshk.rpc.iotc.dto.OperateBankPreferenceQueryDTO;
import com.ctshk.rpc.iotc.entity.OperateBankPreference;
import com.ctshk.rpc.iotc.entity.OperateBankPreferenceProduct;
import com.ctshk.rpc.iotc.mapper.OperateBankPreferenceMapper;
import com.ctshk.rpc.iotc.mapper.OperateBankPreferenceProductMapper;
import com.ctshk.rpc.iotc.req.*;
import com.ctshk.rpc.iotc.service.IOperateBankPreferenceService;
import com.ctshk.rpc.localfun.req.LocalFunResourceReq;
import com.ctshk.rpc.localfun.service.ILocalFunResourceService;
import com.ctshk.rpc.scenic.req.ScenicProductListReq;
import com.ctshk.rpc.scenic.service.IScenicProductService;
import com.ctshk.rpc.season.service.ISeasonFixedProductService;
import com.ctshk.rpc.ship.req.ShipProductPageReq;
import com.ctshk.rpc.ship.service.IShipProductService;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.IMainDataCurrencyService;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.tour.dto.schedule.TripScheduleItocDTO;
import com.ctshk.rpc.tour.service.ISeriesTripScheduleService;
import com.ctshk.rpc.train.service.ITrainProductService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 银联优惠 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-22
 */
@DubboService
public class OperateBankPreferenceServiceImpl extends ServiceImpl<OperateBankPreferenceMapper, OperateBankPreference> implements IOperateBankPreferenceService {

    @Autowired
    private OperateBankPreferenceMapper operateBankPreferenceMapper;
    @Autowired
    private OperateBankPreferenceProductMapper operateBankPreferenceProductMapper;
    @DubboReference
    private ISysUserService sysUserService;
    @DubboReference
    private ISeriesTripScheduleService iSeriesTripScheduleService;
    @DubboReference
    private ISysDepartmentService sysDepartmentService;
    @DubboReference
    private IAirProductService airProductService;
    @DubboReference
    private IAirportExpressService airportExpressService;
    @DubboReference
    private IScenicProductService scenicProductService;
    @DubboReference
    private IBusProductService busProductService;
    @DubboReference
    private ITrainProductService trainProductService;
    @DubboReference
    private ICustomizedTripScheduleService customizedTripScheduleService;
    @DubboReference
    private IShipProductService shipProductService;
    @DubboReference
    private ILocalFunResourceService localFunResourceService;
    @DubboReference
    private ISeasonFixedProductService seasonFixedProductService;
    @DubboReference
    private ISysApprovalService sysApprovalService;
    @DubboReference
    private ISysPermissionService sysPermissionService;
    @DubboReference
    private IFinanceOnAccountCurrencyQuotaService foacqs;
    @DubboReference
    private IFinanceBillService financeBillService;
    @DubboReference
    private IMainDataCurrencyService mainDataCurrencyService;

    /**
     * 新增银联优惠
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(OperateBankPreferenceAddReq req, TokenUser tokenUser) {
        OperateBankPreference operateBankPreference = EntityUtil.copy(req, OperateBankPreference.class);
        //校验优惠代码
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperateBankPreference::getActivityCode, req.getActivityCode());
        if (0 != operateBankPreferenceMapper.selectCount(queryWrapper)) {
            return Result.failed(SystemError.IOTC_40001);
        }
        if (req.getRelationIdList() == null || req.getRelationIdList().size() < 1) {
            return Result.failed(SystemError.IOTC_400025);
        }
        long id = IdWorker.getId();
        operateBankPreference.setId(id);
        operateBankPreference.setIsDeleted(IsDeletedCode.NO.getCode());
        LocalDateTime now = LocalDateTime.now();
        if (req.getSaveStatus() == 1) {
            operateBankPreference.setStatus(OperatePromotionStatus.STATUS_1.getCode());//新增默认未提交
        } else {
            operateBankPreference.setStatus(OperatePromotionStatus.STATUS_2.getCode());//新增默认审批中
        }
        if (req.getDiscountPercent() != null) {
            //如果折扣存在，输入的是0到1之间的就
//            if (req.getDiscountPercent() >= 0 && req.getDiscountPercent() <= 1) {
//                operateBankPreference.setDiscountPercent(req.getDiscountPercent());
//            } else {
//                operateBankPreference.setDiscountPercent(req.getDiscountPercent() / 100);
//            }
            operateBankPreference.setDiscountPercent(req.getDiscountPercent() / 100);
        }
        operateBankPreference.setGmtCreate(now);
        operateBankPreference.setGmtModified(now);
        operateBankPreference.setCreateId(tokenUser.getId());
        operateBankPreference.setModifiedId(tokenUser.getId());
        operateBankPreference.setStockAmount(req.getTotalAmount());
        operateBankPreference.setStockNum(req.getTotalDiscountQuota());
        //新增银联优惠
        int insert = baseMapper.insert(operateBankPreference);
        if (insert > 0 && null != req.getRelationIdList()) {
            OperateBankPreferenceProduct operateBankPreferenceProduct = new OperateBankPreferenceProduct();
            operateBankPreferenceProduct.setCodeId(id);
            operateBankPreferenceProduct.setIsDeleted(IsDeletedCode.NO.getCode());
            operateBankPreferenceProduct.setGmtCreate(now);
            operateBankPreferenceProduct.setGmtModified(now);
            operateBankPreferenceProduct.setCreateId(tokenUser.getId());
            for (Long relationId : req.getRelationIdList()) {
                operateBankPreferenceProduct.setId(IdWorker.getId());
                operateBankPreferenceProduct.setRelationId(relationId);
                //新增银联优惠适用产品
                operateBankPreferenceProductMapper.insert(operateBankPreferenceProduct);
            }
        }
        if (insert > 0 && req.getSaveStatus() == 2) { //审批
            Result<ApprovalStartDTO> approvalResult = sysApprovalService.start(SystemBusinessType.IOTC.getCode(),
                    SysApprovalType.BANKOFFERS_OPRATION.getCode(), id,
                    tokenUser.getId(), null, null);
            if (!approvalResult.isSuccess()) {
                log.error(approvalResult.getMsg());
                return approvalResult;
            }
        }
        return Result.success(id);
    }

    /**
     * 编辑银联优惠
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result update(OperateBankPreferenceUpdateReq req, TokenUser tokenUser) {
        if (req.getRelationIdList() == null || req.getRelationIdList().size() < 1) {
            return Result.failed(SystemError.IOTC_400025);
        }
        OperateBankPreference operateBankPreference = EntityUtil.copy(req, OperateBankPreference.class);
        LocalDateTime now = LocalDateTime.now();
        operateBankPreference.setGmtModified(now);
        if (req.getSaveStatus() == 2) {
            operateBankPreference.setStatus(OperatePromotionStatus.STATUS_2.getCode());
        } else {
            operateBankPreference.setStatus(OperatePromotionStatus.STATUS_1.getCode());
        }
        //判断优惠力度是否变更
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", req.getId());
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());
        OperateBankPreference selectOne = operateBankPreferenceMapper.selectOne(queryWrapper);
        if (selectOne.getDiscountType() != req.getDiscountType()) {
            operateBankPreferenceMapper.updateDiscountTypeById(req.getId());
        }
        //更新银联优惠
        int i = operateBankPreferenceMapper.updateById(operateBankPreference);
        if (i > 0 && CollectionUtils.isNotEmpty(req.getRelationIdList())) {
            //查询银联优惠对应的产品
            QueryWrapper<OperateBankPreferenceProduct> operateBankPreferenceProductQueryWrapper = new QueryWrapper<>();
            queryWrapper.eq("code_id", req.getId());
            List<OperateBankPreferenceProduct> preferenceProductList = operateBankPreferenceProductMapper.selectList(operateBankPreferenceProductQueryWrapper);
            List<Long> relationIdList = new ArrayList<>();
            for (OperateBankPreferenceProduct op : preferenceProductList) {
                relationIdList.add(op.getRelationId());
            }
            //比对银联推广新增对应产品
            OperateBankPreferenceProduct product = new OperateBankPreferenceProduct();
            OperateBankPreferenceProduct newProduct = new OperateBankPreferenceProduct();
            newProduct.setCreateId(tokenUser.getId());
            newProduct.setModifiedId(tokenUser.getId());
            newProduct.setGmtCreate(now);
            newProduct.setGmtModified(now);
            newProduct.setIsDeleted(IsDeletedCode.NO.getCode());
            for (Long newRelationId : req.getRelationIdList()) {
                if (relationIdList.contains(newRelationId)) {
                    product.setCodeId(req.getId());
                    product.setRelationId(newRelationId);
                    product.setIsDeleted(IsDeletedCode.NO.getCode());
                    operateBankPreferenceProductMapper.updateById(product);
                } else {
                    newProduct.setId(IdWorker.getId());
                    newProduct.setRelationId(newRelationId);
                    newProduct.setCodeId(req.getId());
                    operateBankPreferenceProductMapper.insert(newProduct);
                }
            }
            //比对银联优惠减少对应产品
            List<Long> newRelationIdList = req.getRelationIdList();
            for (Long relationId : relationIdList) {
                if (!newRelationIdList.contains(relationId)) {
                    operateBankPreferenceProductMapper.updateByCodeIdAndRelationId(req.getId(), relationId);
                }
            }
        }
        if (i > 0 && req.getSaveStatus() == 2) { //审批
            Result<ApprovalStartDTO> approvalResult = sysApprovalService.start(SystemBusinessType.IOTC.getCode(),
                    SysApprovalType.BANKOFFERS_OPRATION.getCode(), operateBankPreference.getId(),
                    tokenUser.getId(), null, null);
            if (!approvalResult.isSuccess()) {
                log.error(approvalResult.getMsg());
                return approvalResult;
            }
        }
        return Result.success(req.getId());
    }

    @Override
    public Result updateStatus(CodeStatusReq req, TokenUser tokenUser) {
        OperateBankPreference op = new OperateBankPreference();
        op.setId(req.getId());
        op.setStatus(req.getStatus());
        int i = baseMapper.updateById(op);
        if (i > 0) {
            return Result.success();
        }
        return Result.failed(SystemError.CMS_23002);
    }

    @Override
    public Result approvalCode(Long codeId, TokenUser tokenUser) {
        OperateBankPreference obp = baseMapper.selectById(codeId);
        if (obp != null) { //审批
            if (obp.getStatus() == OperatePromotionStatus.STATUS_1.getCode()) {
                obp.setStatus(OperatePromotionStatus.STATUS_2.getCode());
                int i = baseMapper.updateById(obp);
                if (i > 0) {
                    Result<ApprovalStartDTO> approvalResult = sysApprovalService.start(SystemBusinessType.IOTC.getCode(),
                            SysApprovalType.PROMOTION_OPRATION.getCode(), obp.getId(),
                            tokenUser.getId(), null, null);
                    if (!approvalResult.isSuccess()) {
                        log.error(approvalResult.getMsg());
                        return approvalResult;
                    } else {
                        return Result.success();
                    }
                }
            }
        }
        return Result.failed(SystemError.SYS_437);
    }

    /**
     * 查询银联优惠详情
     * 下方链接快速查看适用产品的业务类型
     *
     * @see com.ctshk.common.enums.SystemBusinessType
     */
    @Override
    public OperateBankPreferenceQueryDTO query(OperateBankPreferenceQueryReq req) {
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", req.getId());
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());
        OperateBankPreference operateBankPreference = operateBankPreferenceMapper.selectOne(queryWrapper);
        if (null == operateBankPreference) {
            throw new BusinessException(SystemError.IOTC_40002);
        }
        OperateBankPreferenceQueryDTO bankPreferenceQueryDTO = EntityUtil.copy(operateBankPreference, OperateBankPreferenceQueryDTO.class);
        QueryWrapper<OperateBankPreferenceProduct> op = new QueryWrapper<>();
        op.eq("code_id", req.getId());
        op.eq("is_deleted", IsDeletedCode.NO.getCode());
        List<OperateBankPreferenceProduct> operateBankPreferenceProducts = operateBankPreferenceProductMapper.selectList(op);
        if (CollectionUtils.isNotEmpty(operateBankPreferenceProducts)) {
            List<Long> list = operateBankPreferenceProducts.stream().map(e -> e.getRelationId()).collect(Collectors.toList());
            bankPreferenceQueryDTO.setIdList(list);
            switch (operateBankPreference.getBusinessType()) {
                case 1: //出境遊
                    List<TripScheduleItocDTO> tripScheduleItocDTOS1 = iSeriesTripScheduleService.queryScheduleListByIdList(list, 1);
                    setAirTicketPage(tripScheduleItocDTOS1, bankPreferenceQueryDTO);
                    break;
                case 2://入境遊
                    List<TripScheduleItocDTO> tripScheduleItocDTOS2 = iSeriesTripScheduleService.queryScheduleListByIdList(list, 2);
                    setAirTicketPage(tripScheduleItocDTOS2, bankPreferenceQueryDTO);
                    break;
                case 3://出境定制
                case 4://入境定制
                case 5://會議會獎
                    //3-4-5是同一个接口
                    setAirTicketPage(customizedTripScheduleService.queryByIds(list, operateBankPreference.getBusinessType()), bankPreferenceQueryDTO);
                    break;
                case 6://固定套票
                    String join = org.apache.commons.lang.StringUtils.join(list.toArray(), ",");
                    setAirTicketPage(seasonFixedProductService.getSeasonProductList(join), bankPreferenceQueryDTO);
                    break;
                case 7://動態套票
                    break;
                case 8://酒店
                    break;
                case 9://機票
                    setAirTicketPage(airProductService.operationsCenterGetProductByIds(list).getData(), bankPreferenceQueryDTO);
                    break;
                case 10://火車票
                    setAirTicketPage(trainProductService.queryProductListByIdForIotc(list).getData(), bankPreferenceQueryDTO);
                    break;
                case 11://船票
                    ShipProductPageReq sppr = new ShipProductPageReq();
                    sppr.setProductIds(list);
                    setAirTicketPage(shipProductService.queryShipList2(sppr), bankPreferenceQueryDTO);
                    break;
                case 12://巴士票
                    setAirTicketPage(busProductService.queryProductListByIdForIotc(list).getData(), bankPreferenceQueryDTO);
                    break;
                case 13://機場快線
                    setAirTicketPage(airportExpressService.getListByIds(list), bankPreferenceQueryDTO);
                    break;
                case 14://景點門票
                    ScenicProductListReq splr = new ScenicProductListReq();
                    splr.setIds(list);
                    setAirTicketPage(scenicProductService.getListByIds(splr).getData(), bankPreferenceQueryDTO);
                    break;
                case 15://當地玩樂
                    LocalFunResourceReq lfrr = new LocalFunResourceReq();
                    lfrr.setProductIds(list);
                    setAirTicketPage(localFunResourceService.queryListByProductIds2(lfrr), bankPreferenceQueryDTO);
                    break;
                case 16://簽證
                    break;
                case 17://證件辦理
                    break;
                case 18://商品
                    break;
                case 19://财务中心
                    break;
                case 20://運營中心
                    break;
                case 21://供應商預訂
                    break;
                case 22://系統資源
                    break;
                case 23://套票
                    break;
                case 24://保险
                    break;
            }
        } else {
            bankPreferenceQueryDTO.setIdList(null);
        }
        return bankPreferenceQueryDTO;
    }

    private <T> void setAirTicketPage(List<T> list, OperateBankPreferenceQueryDTO bankPreferenceQueryDTO) {
        if (list != null && list.size() > 0) {
            bankPreferenceQueryDTO.setAirTicketPage((List<Object>) list);
        }
    }

    /**
     * 查询银联优惠列表
     */
    @Override
    public PageResponse<OperateBankPreferenceListDTO> list(OperateBankPreferenceListReq req, TokenUser tokenUser) {
        IPage<OperateBankPreference> page = new Page<>(req.getPageNo(), req.getPageSize());
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        //判断是否有权限查看
        if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {
            if (req.getMenuId() == null) {
                throw new BusinessException(SystemError.SYSTEM_2106);
            }
            Result<List<Long>> permissionResult = sysPermissionService.queryPermission(req.getMenuId(), tokenUser.getId());
            if (!permissionResult.isSuccess()) {
                SystemError result = SystemError.getDefined(permissionResult.getCode());
                throw new BusinessException(result);
            }
            queryWrapper.lambda().in(OperateBankPreference::getCreateId, permissionResult.getData());
        }
        queryWrapper.lambda().ge(null != req.getActivityBegin1(), OperateBankPreference::getActivityBegin, req.getActivityBegin1())
                .le(null != req.getActivityBegin2(), OperateBankPreference::getActivityBegin, req.getActivityBegin2())
                .ge(null != req.getActivityEnd1(), OperateBankPreference::getActivityEnd, req.getActivityEnd1())
                .le(null != req.getActivityEnd2(), OperateBankPreference::getActivityEnd, req.getActivityEnd2())
                .ge(null != req.getGmtCreate1(), OperateBankPreference::getGmtCreate, req.getGmtCreate1())
                .le(null != req.getGmtCreate2(), OperateBankPreference::getGmtCreate, req.getGmtCreate2())
                .eq(null != req.getStatus(), OperateBankPreference::getStatus, req.getStatus())
                .eq(null != req.getCreateId(), OperateBankPreference::getCreateId, req.getCreateId())
                .like(StringUtils.isNotBlank(req.getActivityCode()), OperateBankPreference::getActivityCode, req.getActivityCode())
                .like(StringUtils.isNotBlank(req.getName()), OperateBankPreference::getName, req.getName())
                .eq(OperateBankPreference::getIsDeleted, IsDeletedCode.NO.getCode())
                .orderByDesc(OperateBankPreference::getGmtModified);
        //需定义排序规则:按修改时间倒序
        IPage<OperateBankPreference> iPage = baseMapper.selectPage(page, queryWrapper);
        List<OperateBankPreference> bankPreferenceList = iPage.getRecords();
        List<OperateBankPreferenceListDTO> operateBankPreferenceListDTOList = EntityUtil.copyList(bankPreferenceList, OperateBankPreferenceListDTO.class);
        if (CollectionUtils.isEmpty(operateBankPreferenceListDTOList)) {
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        List<OperateBankPreferenceListDTO> obpl = EntityUtil.copyList(operateBankPreferenceListDTOList, OperateBankPreferenceListDTO.class);
        //填充创建人名称  修改人名称
        Set<Long> ids = obpl.stream().map(e -> e.getCreateId()).collect(Collectors.toSet());
        Set<Long> uids = obpl.stream().map(e -> e.getModifiedId()).collect(Collectors.toSet());
        ids.addAll(uids);
        List<UserDTO> users = sysUserService.getUsers(ids);
        Map<Long, String> us = new HashMap<>();
        users.stream().forEach(e -> us.put(e.getId(), e.getFullName()));
        obpl.stream().forEach(e -> {
            e.setCreateName(us.get(e.getCreateId()));
            e.setModifiedName(us.get(e.getModifiedId()));
        });
        return new PageResponse<>(obpl, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    /**
     * 查询符合條件的银联优惠列表
     * 标记一下逻辑好像有点问题
     */
    @Override
    public List<OperateBankPreferenceListDTO> conformList(OperateBankConformReq req) {
        QueryWrapper<OperateBankPreferenceProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperateBankPreferenceProduct::getRelationId, req.getRelationId())
                .eq(OperateBankPreferenceProduct::getIsDeleted, IsDeletedCode.NO.getCode());
        List<OperateBankPreferenceProduct> OperateBankPreferenceProductList = operateBankPreferenceProductMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(OperateBankPreferenceProductList)) {
            return new ArrayList<>();
        }
        //获取当期时间
        LocalDateTime now = LocalDateTime.now();
        String week = String.valueOf(now.getDayOfWeek().getValue());
        QueryWrapper<OperateBankPreference> wrapper = new QueryWrapper<>();
        List<Long> longs = OperateBankPreferenceProductList.stream().map(e -> e.getCodeId()).collect(Collectors.toList());
        wrapper.lambda().in(OperateBankPreference::getId, longs)
                .eq(OperateBankPreference::getStatus, OperatePromotionStatus.STATUS_4.getCode())
                .gt(OperateBankPreference::getStockAmount, 0)
                .gt(OperateBankPreference::getStockNum, 0)
                .eq(OperateBankPreference::getBusinessType, req.getBusinessType());
        List<OperateBankPreference> bankPreferenceList = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(bankPreferenceList)) {
            return new ArrayList<>();
        }
        for (OperateBankPreference operateBankPreference : bankPreferenceList) {
            //判断条件(是否符合活动有效期)
            if (!(now.isAfter(operateBankPreference.getActivityBegin()) && now.isBefore(operateBankPreference.getActivityEnd()))) {
                bankPreferenceList.remove(operateBankPreference);
                continue;
            }
            //判断条件(是否符合活动周期)
            if (operateBankPreference.getActivityCycle() != OperatePromotionActivityCycle.ACTIVITY_CYCLE_1.getCode()) {
                String[] strings = operateBankPreference.getActivityCycleWeeks().split(",");
                List<String> list = Arrays.asList(strings);
                if (!list.contains(week)) {
                    bankPreferenceList.remove(operateBankPreference);
                    continue;
                }
            }
            //判断是否符合优惠对象
            String discountObjectsJson = JSON.toJSONString(operateBankPreference.getDiscountObjectsJson());
            List<OperateJson> operateJsonList = JSON.parseArray(JSON.parseArray(discountObjectsJson).toJSONString(), OperateJson.class);
            boolean isDiscountObject = true;
            for (OperateJson operateJson : operateJsonList) {
                if (operateJson.getId().equals(req.getDiscountObjectId())) {
                    isDiscountObject = false;

                }
            }
            if (isDiscountObject) {
                bankPreferenceList.remove(operateBankPreference);
                continue;
            }
            //判断是否符合渠道范围
            boolean isChannel = true;
            String channelsJson = JSON.toJSONString(operateBankPreference.getChannelsJson());
            List<OperateJson> channelsJsonList = JSON.parseArray(JSON.parseArray(channelsJson).toJSONString(), OperateJson.class);
            for (OperateJson operateJson : channelsJsonList) {
                if (operateJson.getId().equals(req.getChannelId())) {
                    isChannel = false;
                }
            }
            if (isChannel) {
                bankPreferenceList.remove(operateBankPreference);
                continue;
            }
            //判断是否符合适用部门
            if (CollectionUtils.isNotEmpty(operateBankPreference.getDepartmentsJson())) {
                boolean isDepart = true;
                String departmentsJson = JSON.toJSONString(operateBankPreference.getDepartmentsJson());
                List<OperateJson> departmentsJsonList = JSON.parseArray(JSON.parseArray(departmentsJson).toJSONString(), OperateJson.class);
                for (OperateJson department : departmentsJsonList) {
                    if (sysDepartmentService.isExist(department.getId(), req.getUserId())) {
                        isDepart = false;
                    }
                }
                if (isDepart) {
                    bankPreferenceList.remove(operateBankPreference);
                    continue;
                }
            }
        }
        if (CollectionUtils.isEmpty(bankPreferenceList)) {
            return new ArrayList<>();
        }
        List<OperateBankPreferenceListDTO> operateBankPreferenceListDTOS = EntityUtil.copyList(bankPreferenceList, OperateBankPreferenceListDTO.class);
        return operateBankPreferenceListDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deduct(OperateBankDeductReq req, TokenUser tokenUser) {
        OperateBankPreference operateBankPreference = baseMapper.selectById(req.getId());
        LocalDateTime now = LocalDateTime.now();
        //是否符合活动有效期
        //是否符合活动周期
        if (!getTimeBool(operateBankPreference)) {
            return Result.failed(SystemError.IOTC_400012);
        }
        //优惠金额
        BigDecimal discount;
        //判断优惠方式
        if (operateBankPreference.getDiscountType() == OperatePromotionDiscountType.DISCOUNT_TYPE_1.getCode()) {
            //判断优惠余额是否满足优惠条件
            int i = operateBankPreference.getFullAmount().compareTo(req.getTotalPaidIn());
            if (i > 0) {
                return Result.failed(SystemError.IOTC_400014);
            }
            discount = operateBankPreference.getReductionAmount();
        } else {
            //实际折扣优惠金额 = （消费金额*享受减扣优惠率0.8）
            discount = req.getTotalPaidIn().multiply(BigDecimal.valueOf(operateBankPreference.getDiscountPercent()));
            int i = discount.compareTo(operateBankPreference.getMaxDiscount());
            //如果本次优惠金额大于最大优惠金额 （则本次优惠最大金额）
            if (i > 0) {
                discount = operateBankPreference.getMaxDiscount();
            }
        }
        int i = operateBankPreference.getStockAmount().compareTo(discount);
        //活动金额不足
        if (i < 0) {
            return Result.failed(SystemError.IOTC_400015);
        }
        //名额不足
        if (operateBankPreference.getStockNum() != null && operateBankPreference.getStockNum() < 1) {
            return Result.failed(SystemError.IOTC_400013);
        }
        //判断是否在卡号范围  每个银行的卡的卡段都不一样
        if (!getCardNumbersBool(operateBankPreference.getCardNumbers(), req.getCardNumber())) {
            return Result.failed(SystemError.IOTC_400021);
        }
        //判断是否属于业务类型
        if (operateBankPreference.getBusinessType() != req.getBusinessType()) {
            return Result.failed(SystemError.IOTC_400020);
        }
        //判断是否是适用产品
        OperateBankPreferenceProduct obpp = getProdectBool(req.getId(), req.getRelationId());
        if (obpp == null) {
            return Result.failed(SystemError.IOTC_400016);
        }
        //判断是否符合优惠对象
        if (!getDiscountObjectsJsonBool(operateBankPreference.getDiscountObjectsJson(), req.getDiscountObjectId())) {
            return Result.failed(SystemError.IOTC_400017);
        }
        //判断是否符合渠道范围
        if (!getChannelsJsonBool(operateBankPreference.getChannelsJson(), req.getChannelId())) {
            return Result.failed(SystemError.IOTC_400018);
        }
//        //判断是否符合适用部门
//        if (!getDepartmentsJsonBool(operateBankPreference.getDepartmentsJson(), req.getUserId())) {
//            return Result.failed(SystemError.IOTC_400019);
//        }
        OperateBankPreference preference = new OperateBankPreference();
        //等于空就名额无限
        if (operateBankPreference.getStockNum() != null) {
            //剩余优惠人次 -1
            int newStockNum = operateBankPreference.getStockNum() - 1;
            if (newStockNum <= 0) {
                return Result.failed(SystemError.IOTC_400013);
            }
            preference.setStockNum(newStockNum);
        }
        //剩余活动金额 减扣
        BigDecimal newStockAmount = operateBankPreference.getStockAmount().subtract(discount);
        int isEnough = newStockAmount.compareTo(BigDecimal.valueOf(0));
        if (isEnough > -1) {
            return Result.failed(SystemError.IOTC_400015);
        }
        preference.setId(req.getId());
        preference.setStockAmount(operateBankPreference.getStockAmount().subtract(discount));
        preference.setModifiedId(tokenUser.getId());
        preference.setGmtModified(now);
        int update = baseMapper.updateById(preference);
        if (update > 0) {
            return Result.success();
        }
        //银行大客户新增 一笔收款记录
//        BillAddCollectionReq bacr = EntityUtil.copy(req, BillAddCollectionReq.class);
//        bacr.setCollectionAmount(discount);//实际优惠金额
//        bacr.setCollectionTime(LocalDateTime.now());//消费时间当前
//        List<Long> list = new ArrayList<>();
//        list.add(req.getRelationId());
//        bacr.setProductId(list);//产品ID
//        bacr.setUserId(tokenUser.getId());//操作用户
//        List<BillAddCollectionReq> list2 = new ArrayList<>();
//        list2.add(bacr);
//        Result result = financeBillService.addCollection(list2);
//        List<Long> lists = (List<Long>) result.getData();
//        if (lists != null && lists.size() > 0) {
//
//        }
        return Result.failed(SystemError.IOTC_40007);
    }

    @Override
    public Result<OperateBankPreferenceQueryDTO> queryConform(OperateBankConformQueryReq req) {
        try {
            QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OperateBankPreference::getId, req.getId())
                    .eq(OperateBankPreference::getIsDeleted, IsDeletedCode.NO.getCode())
                    .eq(OperateBankPreference::getBusinessType, req.getBusinessType());
            OperateBankPreference operateBankPreference = baseMapper.selectOne(queryWrapper);
            if (operateBankPreference == null) {
                return Result.failed(SystemError.IOTC_40002);
            }
            //是否符合活动有效期
            //是否符合活动周期
            if (!getTimeBool(operateBankPreference)) {
                return Result.failed(SystemError.IOTC_400012);
            }
            //优惠金额
            BigDecimal discount;
            //判断优惠方式
            if (operateBankPreference.getDiscountType() == OperatePromotionDiscountType.DISCOUNT_TYPE_1.getCode()) {
                //判断优惠余额是否满足优惠条件
                int i = req.getTotalPaidIn().compareTo(operateBankPreference.getFullAmount());
                if (i < 0) {
                    return Result.failed(SystemError.IOTC_400014);
                }
                discount = operateBankPreference.getReductionAmount();
            } else {
                //折扣优惠金额 折扣率为小数
                discount = req.getTotalPaidIn().multiply(BigDecimal.valueOf(operateBankPreference.getDiscountPercent()));
                int i = discount.compareTo(operateBankPreference.getMaxDiscount());
                if (i > 0) {
                    discount = operateBankPreference.getMaxDiscount();
                }
            }
            //判断剩余金额 对比 优惠金额
            int i = operateBankPreference.getStockAmount().compareTo(discount);
            if (i < 0) {
                return Result.failed(SystemError.IOTC_400015);
            }
            //判断是否在卡号范围
            if (!getCardNumbersBool(operateBankPreference.getCardNumbers(), req.getCardNumber())) {
                return Result.failed(SystemError.IOTC_400021);
            }
            //判断是否属于业务类型
            if (operateBankPreference.getBusinessType() != req.getBusinessType()) {
                return Result.failed(SystemError.IOTC_400020);
            }
            //判断是否是适用产品
            if (getProdectBool(req.getId(), req.getRelationId()) == null) {
                return Result.failed(SystemError.IOTC_400016);
            }
            //判断是否符合优惠对象
            if (!getDiscountObjectsJsonBool(operateBankPreference.getDiscountObjectsJson(), req.getDiscountObjectId())) {
                return Result.failed(SystemError.IOTC_400017);
            }
            //判断是否符合渠道范围
            if (!getChannelsJsonBool(operateBankPreference.getChannelsJson(), req.getChannelId())) {
                return Result.failed(SystemError.IOTC_400018);
            }
            //判断是否符合适用部门
//            if (!getDepartmentsJsonBool(operateBankPreference.getDepartmentsJson(), req.getUserId())) {
//                return Result.failed(SystemError.IOTC_400019);
//            }
            //判断银行大客户有没有剩余挂账金额  不足就失败
//            QueryQuotaReq qqr = new QueryQuotaReq();
//            qqr.setAccountType(1);//账户类型 1 大客户/代理商挂账,2 内部中心挂账  临时类型没有枚举写死
//            qqr.setAccountId(operateBankPreference.getBankId());//银行ID
//            MainDataCurrencyListDTO mdc = mainDataCurrencyService.getCurrencyByCode("HKD");
//            if (mdc == null) { //HKD 币种无效或不存在
//                return Result.failed(SystemError.IOTC_400022);
//            }
//            qqr.setCurrencyId(mdc.getId());//币种ID
//            Result<QueryQuotaDTO> queryQuotaDTOResult = foacqs.queryQuota(qqr);
//            BigDecimal availableAmount = queryQuotaDTOResult.getData().getAvailableAmount();//大客户可用挂账余额
//            //判断大客户可挂账余额 对比 优惠金额
//            int ii = availableAmount.compareTo(discount);
//            if (ii < 0) {
//                return Result.failed(SystemError.IOTC_400023);
//            }
            OperateBankPreferenceQueryDTO queryDTO = EntityUtil.copy(operateBankPreference, OperateBankPreferenceQueryDTO.class);
            queryDTO.setDiscount(discount);
            return Result.success(queryDTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(SystemError.IOTC_40003);
    }

    @Override
    public Result refundUpdate(OperateBankRefundReq req, TokenUser tokenUser) {
        OperateBankPreference operateBankPreference = baseMapper.selectById(req.getId());
        LocalDateTime now = LocalDateTime.now();
        //判断是否在卡号范围
        if (!getCardNumbersBool(operateBankPreference.getCardNumbers(), req.getCardNumber())) {
            return Result.failed(SystemError.IOTC_400021);
        }
        //判断是否属于业务类型
        if (operateBankPreference.getBusinessType() != req.getBusinessType()) {
            return Result.failed(SystemError.IOTC_400020);
        }
        //判断是否是适用产品
        if (getProdectBool(req.getId(), req.getRelationId()) == null) {
            return Result.failed(SystemError.IOTC_400016);
        }
        //判断是否符合优惠对象
        if (!getDiscountObjectsJsonBool(operateBankPreference.getDiscountObjectsJson(), req.getDiscountObjectId())) {
            return Result.failed(SystemError.IOTC_400017);
        }
        //判断是否符合渠道范围
        if (!getChannelsJsonBool(operateBankPreference.getChannelsJson(), req.getChannelId())) {
            return Result.failed(SystemError.IOTC_400018);
        }
        //判断是否符合适用部门
//        if (!getDepartmentsJsonBool(operateBankPreference.getDepartmentsJson(), req.getUserId())) {
//            return Result.failed(SystemError.IOTC_400019);
//        }
        OperateBankPreference preference = new OperateBankPreference();
        if (operateBankPreference.getTotalDiscountQuota() != null) {
            //扣减名额加上
            preference.setTotalDiscountQuota(operateBankPreference.getTotalDiscountQuota() + 1);
        }
        preference.setId(req.getId());
        preference.setStockAmount(operateBankPreference.getStockAmount().add(req.getRefundTotalPaidIn()));
        preference.setModifiedId(tokenUser.getId());
        preference.setGmtModified(now);
        int update = baseMapper.updateById(preference);
        if (update > 0) {
            return Result.success();
        }
        //添加一条退款记录
//        BillAddRefundReq barr = EntityUtil.copy(req, BillAddRefundReq.class);
//        barr.setCollectionAmount(req.getRefundTotalPaidIn());//实际优惠的金额
//        barr.setRefundTime(LocalDateTime.now());//退款时间当前
//        List<Long> list = new ArrayList<>();
//        list.add(req.getRelationId());
//        barr.setProductId(list);//产品ID
//        barr.setUserId(tokenUser.getId());//操作用户
//        List<BillAddRefundReq> list2 = new ArrayList<>();
//        list2.add(barr);
//        Result result = financeBillService.addRefund(list2);
//        List<Long> lists = (List<Long>) result.getData();
//        if (lists != null && lists.size() > 0) {
//
//        }
        return Result.failed(SystemError.IOTC_40005);
    }

    @Override
    public List<Long> queryRelationIdList(Integer businessType) {
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperateBankPreference::getBusinessType, businessType)
                .eq(OperateBankPreference::getStatus, OperatePromotionStatus.STATUS_4.getCode())
                .eq(OperateBankPreference::getIsDeleted, IsDeletedCode.NO.getCode())
                .orderByDesc(OperateBankPreference::getGmtModified);
        List<OperateBankPreference> bankPreferenceList = baseMapper.selectList(queryWrapper);
        //获取当期时间
        LocalDateTime now = LocalDateTime.now();
        String week = String.valueOf(now.getDayOfWeek().getValue());
        List<Long> codeIdList = new ArrayList<>();
        for (OperateBankPreference operateBankPreference : bankPreferenceList) {
            //判断条件(是否符合活动有效期)
            if (!(now.isAfter(operateBankPreference.getActivityBegin()) && now.isBefore(operateBankPreference.getActivityEnd()))) {
                bankPreferenceList.remove(operateBankPreference);
                continue;
            }
            //判断条件(是否符合活动周期)
            if (operateBankPreference.getActivityCycle() != OperatePromotionActivityCycle.ACTIVITY_CYCLE_1.getCode()) {
                String[] strings = operateBankPreference.getActivityCycleWeeks().split(",");
                List<String> list = Arrays.asList(strings);
                if (!list.contains(week)) {
                    bankPreferenceList.remove(operateBankPreference);
                    continue;
                }
            }
            //判斷條件(剩餘金額或剩餘名額不為0)
            if (operateBankPreference.getStockNum() == 0 || operateBankPreference.getStockAmount().equals(0)) {
                bankPreferenceList.remove(operateBankPreference);
                continue;
            }
            codeIdList.add(operateBankPreference.getId());
        }
        if (CollectionUtils.isEmpty(codeIdList)) {
            return null;
        }
        List<Long> list = new ArrayList<>();
        QueryWrapper<OperateBankPreferenceProduct> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(OperateBankPreferenceProduct::getCodeId, codeIdList);
        List<OperateBankPreferenceProduct> operateBankPreferenceProducts = operateBankPreferenceProductMapper.selectList(wrapper);
//        List<OperateBankPreferenceProduct> operateBankPreferenceProducts = operateBankPreferenceProductMapper.selectIds(codeIdList);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        for (OperateBankPreferenceProduct operateBankPreferenceProduct : operateBankPreferenceProducts) {
            list.add(operateBankPreferenceProduct.getRelationId());
        }
        List<Long> myList = list.stream().distinct().collect(Collectors.toList());
        return myList;
    }

    @Override
    public Result approval(OperateBankApprovalReq req) {
        if (req.getApprovalId() == null) {
            return Result.failed(SystemError.SYS_402);
        }
        if (!ApprovalStatus.isCheckStatus(req.getApprovalStatus())) {
            return Result.failed(SystemError.SYS_402);
        }
        //审批前查询银联优惠信息
        QueryWrapper<OperateBankPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperateBankPreference::getId, req.getBusinessId())
                .eq(OperateBankPreference::getIsDeleted, IsDeletedCode.NO);
        OperateBankPreference obp = baseMapper.selectOne(queryWrapper);
        if (obp == null) {
            return Result.failed(SystemError.SYS_411);
        }
        //审批
        Result<ApprovalCheckDTO> result = sysApprovalService.check(req.getApprovalId(), req.getUserId(),
                req.getApprovalStatus(), req.getRemark());
        if (!result.isSuccess()) {
            SystemError systemError = SystemError.getDefined(result.getCode());
            return Result.failed(systemError);
        }
        if (result.getData() == null || !result.getData().getIsFinish()) {
            return Result.success();
        }
        //审批状态（0：撤回，4：审批不通过，3：审批通过）
        if (req.getApprovalStatus() == SupplierAddCheckStatus.REVIEW_YES.getCode()) {
            //审批通过
            obp.setStatus(OperatePromotionStatus.STATUS_4.getCode());
        } else if (req.getApprovalStatus() == SupplierAddCheckStatus.REVIEW_NO.getCode()) {
            //审批不通过
            obp.setStatus(OperatePromotionStatus.STATUS_3.getCode());
        } else {
            //撤回
            obp.setStatus(OperatePromotionStatus.STATUS_1.getCode());
        }
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        obp.setModifiedId(req.getUserId());
        obp.setGmtModified(nowLocalDateTime);
        baseMapper.updateById(obp);
        return Result.success();
    }

    @Override
    public void reflush() {
        QueryWrapper<OperateBankPreference> qwobpf = new QueryWrapper<>();
        qwobpf.lambda().eq(OperateBankPreference::getIsDeleted, IsDeletedCode.NO.getCode())
                .le(OperateBankPreference::getActivityEnd, LocalDateTime.now())
                .eq(OperateBankPreference::getStatus, OperatePromotionStatus.STATUS_4.getCode());
        List<OperateBankPreference> obpf = baseMapper.selectList(qwobpf);
        //查到过期的银联优惠就修改为失效
        if (obpf != null && obpf.size() > 0) {
            obpf.stream().forEach(e -> {
                e.setStatus(OperatePromotionStatus.STATUS_6.getCode());
                baseMapper.updateById(e);
            });
        }
    }

    private boolean getDepartmentsJsonBool(List<OperateJson> djs, Long userId) {
        if (djs == null || djs.size() == 0) {
            return true;//不选部门所有都可以用直接跳过
        }
        String s = JSON.toJSONString(djs);
        JSONArray objects = JSONArray.parseArray(s);
        List<OperateJson> list = objects.toJavaList(OperateJson.class);
        //判断是否符合适用部门
        if (list != null && list.size() > 0) {
            for (OperateJson department : list) {
                if (sysDepartmentService.isExist(department.getId(), userId)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean getChannelsJsonBool(List<OperateJson> cjs, Long channelId) {
        if (cjs == null || cjs.size() == 0) {
            //不限制渠道范围
            return true;
        }
        String s = JSON.toJSONString(cjs);
        JSONArray objects = JSONArray.parseArray(s);
        List<OperateJson> list = objects.toJavaList(OperateJson.class);
        //判断是否符合渠道范围
        if (list != null && list.size() > 0) {
            List<Long> collect = list.stream().map(e -> e.getId()).collect(Collectors.toList());
            //如果配置了渠道范围，切又不在配置的渠道范围内就错误
            if (!collect.contains(channelId)) {
                return false;
            }
            return true;
        } else {
            return false;
        }
    }

    private boolean getDiscountObjectsJsonBool(List<OperateJson> ojs, Long discountObjectId) {
        if (ojs == null || ojs.size() == 0) {
            //不限制优惠对象
            return true;
        }
        String s = JSON.toJSONString(ojs);
        JSONArray objects = JSONArray.parseArray(s);
        List<OperateJson> list = objects.toJavaList(OperateJson.class);
        //判断是否符合优惠对象
        if (list != null && list.size() > 0) {
            List<Long> collect = list.stream().map(e -> e.getId()).collect(Collectors.toList());
            //如果配置了优惠对象，切又不在配置的范围内就错误
            if (collect.contains(discountObjectId)) {
                return true;
            }
        }
        return false;
    }

    private OperateBankPreferenceProduct getProdectBool(Long id, Long relationId) {
        //判断是否是适用产品
        QueryWrapper<OperateBankPreferenceProduct> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OperateBankPreferenceProduct::getCodeId, id)
                .eq(OperateBankPreferenceProduct::getIsDeleted, IsDeletedCode.NO.getCode())
                .eq(OperateBankPreferenceProduct::getRelationId, relationId);
        return operateBankPreferenceProductMapper.selectOne(wrapper);

    }

    private boolean getCardNumbersBool(String cardNumbers, String cardNumber) {
        //判断是否在卡号范围
        if (StringUtils.isBlank(cardNumber) || StringUtils.isBlank(cardNumbers)) {
            return false;
        }
        String[] operateCardNumber = cardNumbers.split(",");
        for (int m = 0; m < operateCardNumber.length; m++) {
            //卡段范围比较成功
            if (cardNumber.startsWith(operateCardNumber[m])) {
                return true;
            }
        }
        return false;
    }

    private boolean getTimeBool(OperateBankPreference operateBankPreference) {
        LocalDateTime now = LocalDateTime.now();
        String week = String.valueOf(now.getDayOfWeek().getValue());
        //是否符合活动有效期
        if (!(now.isAfter(operateBankPreference.getActivityBegin()) && now.isBefore(operateBankPreference.getActivityEnd()))) {
            return false;
        }
        //是否符合活动周期
        if (operateBankPreference.getActivityCycle() == OperatePromotionActivityCycle.ACTIVITY_CYCLE_2.getCode()) {
            String[] strings = operateBankPreference.getActivityCycleWeeks().split(",");
            List<String> list = Arrays.asList(strings);
            if (!list.contains(week)) {
                return false;
            }
        }
        return true;
    }

}
